<?php
/**
 * Created by PhpStorm.
 * Author: 芸签cms www.yunqiancms.com
 * User: sun
 * Date: 2022/7/7
 * Time: 5:25 PM
 */
namespace app\common\services\plugin;

use ArrayAccess;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Contracts\Support\Arrayable;
use app\common\models\Plugin as PluginModel;
use app\common\helpers\Cache;//这里的其实不用区分site_id,先不用管


class Plugin implements Arrayable, ArrayAccess
{
    const CACHE_KEY_PACKAGE_PRE = 'app:common:services:plugin:Plugin:plugin_package:';
    /**
     * @var PluginApplication
     */
    protected $pluginApp;


    protected $path;//plugin路径

    protected $dirname;

    protected $packageInfo;

    protected $installed = true;

    protected $enabled = false;

    public function __construct($path){
        $this->path = $path;
        $this->packageInfo = $this->getPackageInfo();
    }
    public function getPackageInfo(){
        $cacheKey = self::CACHE_KEY_PACKAGE_PRE. array_last(explode('/', $this->path));
        $package = Cache::get($cacheKey);
        if (!$package) {
            $package = app('files')->get($this->path . "/package.json");
            Cache::put($cacheKey,$package,120);
        }
        return json_decode($package, true);
    }
    public function __get($name){
        return $this->packageInfoAttribute($name);
    }
    public function __isset($name){
        return isset($this->{$name}) || $this->packageInfoAttribute(Str::snake($name, '-'));
    }
    /**
     * 获取package中某个属性
     * @param $name
     * @return null
     */
    public function packageInfoAttribute($name){
        if (!array_key_exists($name, $this->packageInfo)) {
            return null;
        }
        return $this->packageInfo[$name];
    }
    public function setInstalled($installed){
        $this->installed = $installed;

        return $this;
    }
    public function isInstalled()
    {
        return $this->installed;
    }

    public function getDirname()
    {
        return $this->name;
    }

    public function setDirname($dirname)
    {
        $this->dirname = $dirname;

        return $this;
    }

    public function getNameSpace()
    {
        return $this->namespace;
    }

    public function setNameSpace($namespace)
    {
        $this->namespace = $namespace;

        return $this;
    }
    public function setVersion($version)
    {
        $this->version = $version;

        return $this;
    }

    public function getVersion()
    {
        return $this->version;
    }
    public function setEnabled($enabled)
    {
        $this->enabled = $enabled;
        return $this;
    }

    public function isEnabled()
    {
        return app('plugins')->isEnabled($this->name);
    }
    public function getPath()
    {
        return $this->path;
    }
    /**
     * Get the instance as an array.
     *
     * @return array
     */
    public function toArray()
    {
        return (array)array_merge([
            'name' => $this->name,
            'version' => $this->getVersion(),
            'path' => $this->path
        ], $this->packageInfo);
    }
    public function app()
    {
        if (!isset($this->pluginApp)) {

            $pluginApplicationClass = $this->namespace . '\\' . 'PluginApplication';

            if (class_exists($pluginApplicationClass)) {

                $this->pluginApp = new $pluginApplicationClass($this);
            } else {

                $this->pluginApp = new PluginApplication($this);
            }
        }
        return $this->pluginApp;
    }
    /**
     * Whether a offset exists
     * @link https://php.net/manual/en/arrayaccess.offsetexists.php
     * @param mixed $offset <p>
     * An offset to check for.
     * </p>
     * @return boolean true on success or false on failure.
     * </p>
     * <p>
     * The return value will be casted to boolean if non-boolean was returned.
     * @since 5.0.0
     */
    public function offsetExists($offset)
    {
        // TODO: Implement offsetExists() method.
    }

    /**
     * Offset to retrieve
     * @link https://php.net/manual/en/arrayaccess.offsetget.php
     * @param mixed $offset <p>
     * The offset to retrieve.
     * </p>
     * @return mixed Can return all value types.
     * @since 5.0.0
     */
    public function offsetGet($offset)
    {
        // TODO: Implement offsetGet() method.
    }

    /**
     * Offset to set
     * @link https://php.net/manual/en/arrayaccess.offsetset.php
     * @param mixed $offset <p>
     * The offset to assign the value to.
     * </p>
     * @param mixed $value <p>
     * The value to set.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetSet($offset, $value)
    {
        // TODO: Implement offsetSet() method.
    }

    /**
     * Offset to unset
     * @link https://php.net/manual/en/arrayaccess.offsetunset.php
     * @param mixed $offset <p>
     * The offset to unset.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetUnset($offset)
    {
        // TODO: Implement offsetUnset() method.
    }
}